// -----------------------------------------------------------------------------
//
// Work is licensed by Arthur Fermi (C)2008-2011,
// patches are licensed by Mirella Dallagio (C)2011
// under Creative Commons Attribution-Share Alike 3.0 Unported License
// To receive a copy of this license please visit
// http://creativecommons.org/licenses/by-sa/3.0/
//
// You are free to copy, distribute, transmit and adapt the work
// under the following conditions:
//
// You must attribute the work in the manner specified by the 
// author(s) or licensor (but not in any way that suggests that 
// they endorse you or your use of the work). 
//
// If you alter, transform, or build upon this work in any way,
// you may distribute the resulting work only under the same or 
// similar license to this one. 
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See points (6) and (7) of the license for more details.
//
// -----------------------------------------------------------------------------
//
// zAF_CmdLine 1.01     - 2011-04-28 - initial simnet release
// zAF_CmdLine 1.01-md3 - 2011-05-01 - fix for unresolved name2key requests,
//                                     emits a dialog on failure and accepts 
//                                     banning by key rather than by name too
//
// -----------------------------------------------------------------------------
// Do not change anything below here or you will likely break something
// -----------------------------------------------------------------------------
// compile with lsl2
// -----------------------------------------------------------------------------

// Command Line Channel
integer gintCMDCC = 6;

// URL to the Simnet website
string    gstrURL;    

// URL to use for Name2Key, this should work it is hosted by google and uses SL itself to lookup the data.
string  gstrN2KURL = "http://name2key.appspot.com/?name=";

// Global Variables
    key     gkeyAvatar;         // Who is in trouble
    string  gstrAvatar;         // Avatar to lookup
    string  gstrFunction;       // What function to perform (ban, eject, etc)
    string  gstrHelp;           // Help Text
    string  gstrMediaURL;       // Music/Video URL
    key     reqid;              // http request id 
    string  gstrInfoMsg;        // Used to build the info message   
    
    // Communications
    integer gintTempListen;     // Temp Listen Device
    integer gintTempDCC;        // Temp Dialog Listen
    integer gintDCC;            // Dialog Communications Channel
    integer gintWebRequest;     // Type of web request, 1 = Name2Key 2 = Info Request
    
    
funAction(float fltHours)
{    
    if (gstrFunction == "ban")
    {
        // Build message string 
        llMessageLinked(1, 666, "Banned^" + (string)gkeyAvatar + "^" + gstrAvatar + "^" + (string)fltHours, NULL_KEY);
        
        // Notify manager of action
        llOwnerSay(gstrAvatar + " was banned for " + (string)fltHours + " hours (0 = forever) and sent home");    
    }
    else if (gstrFunction == "eject")
    {
        // Build message string    
        llMessageLinked(1, 666, "Ejected^" + (string)gkeyAvatar + "^" + gstrAvatar + "^N/A", NULL_KEY);
        
        // Notify manager of action    
        llOwnerSay(gstrAvatar + " was ejected.");
    }
    else if (gstrFunction == "unban")
    {
        // Build message string    
        llMessageLinked(1, 666, "Unbanned^" + (string)gkeyAvatar + "^" + gstrAvatar + "^N/A", NULL_KEY);
        
        // Notify manager of action    
        llOwnerSay(gstrAvatar + " was unbanned.");
    }
    else if (gstrFunction == "home")
    {
        // Build message string    
        llMessageLinked(1, 666, "Home^" + (string)gkeyAvatar + "^" + gstrAvatar + "^N/A", NULL_KEY);
      
        // Notify manager of action
        llOwnerSay(gstrAvatar + " was sent home.");    
    }
    gstrFunction = "";
    // Turn of Timer and Listners, not needed here
    llListenRemove(gintTempListen);
    llListenRemove(gintTempDCC);
    llSetTimerEvent(0);
}

default
{
    state_entry()
    {
        // Setup the device
        gintDCC = llCeil(llFrand(10000.0));
        
        // Listen for commmands
        llListen(gintCMDCC,"", llGetOwner(), "");
        
        // Get URL for web site
        llMessageLinked(LINK_SET, 333, "Getting URL", NULL_KEY);
        
        // Configure Help Message
        gstrHelp = "\n    -------------------[ SimNet Toolbar Command Line Usage ]-------------------\n      /" + (string)gintCMDCC + " info name       Gets avatar name, key, in sim status, and location.\n      /" + (string)gintCMDCC + " ban name/key    Bans the avatar\n      /" + (string)gintCMDCC + " home name       Sends the avatar home\n      /" + (string)gintCMDCC + " unban name      Unbans the avatar\n      /" + (string)gintCMDCC + " music url       Changes the music url on all parcels\n      /" + (string)gintCMDCC + " video url       Changes the video url on all parcels\n      /" + (string)gintCMDCC + " slurl           Generate a SLURL\n      /" + (string)gintCMDCC + " listen On|Off   Turns the listener on and off\n      /" + (string)gintCMDCC + " radar On|Off    Turns the radar on and off\n      /" + (string)gintCMDCC + " perfmon On|Off  Turns the performance monitor on and off\n      /" + (string)gintCMDCC + " help            displays this\n";
      
        // display help
        //llOwnerSay(gstrHelp);
        
        llOwnerSay("Commandline Ready"); 
   }
   
    listen(integer channel, string name, key id, string message)
    {
        if (channel == gintCMDCC)
        {
            // Convert command to list
            list lstTempCmd = llParseString2List(message, [" "], [""]);
            
            // Get Function
            gstrFunction = llToLower(llList2String(lstTempCmd, 0));
            
            if (gstrFunction == "ban" || gstrFunction == "eject" || gstrFunction == "home" || gstrFunction == "unban"|| gstrFunction == "info")
            {
                gintWebRequest = 1;
                
                // Lookup Avatars Key
                string first =  llList2String(lstTempCmd, 1);
                string second = llList2String(lstTempCmd, 2);
                
                if( second == "" && llStringLength( first ) == 36 && llGetListLength( llParseString2List( first, ["-"], [] )) == 5 )
                {
                    // UGLY HACK, due to the huge refactoring needed to do things properly,
                    // we go anyway through the http service for now getting a failure we will ignore.
                    // we could do llRequestAgentData, but, again we need a refactoring first
                    gkeyAvatar = first;
                    gstrAvatar = llKey2Name( gkeyAvatar ); if( gstrAvatar == "" ) gstrAvatar = first;
                }
                else if( second == "" )
                {
                    gstrAvatar = llList2String(lstTempCmd, 1) + " Resident";
                    gkeyAvatar = NULL_KEY;
                }
                else
                {
                    gstrAvatar = llList2String(lstTempCmd, 1) + " " + llList2String(lstTempCmd, 2);
                    gkeyAvatar = NULL_KEY;
                }

                // Name2Key
                reqid = llHTTPRequest(gstrN2KURL + llEscapeURL(gstrAvatar), [], "" );                  
            }
            else if (gstrFunction == "music")
            {
                // Build message string    
                llMessageLinked(1, 666, "Music^" + gstrMediaURL + "^None^N/A", NULL_KEY);
              
                // Notify manager of action
                llOwnerSay("Music URL was set to " + gstrMediaURL);                
            }
            else if (gstrFunction == "video")
            {
                // Build message string    
                llMessageLinked(1, 666, "Video^" + gstrMediaURL + "^None^N/A", NULL_KEY);
              
                // Notify manager of action
                llOwnerSay("Video URL was set to " + gstrMediaURL);                
            }
            else if (gstrFunction == "slurl")
            {
                string strSLURL;
                vector vecPos;
  
                // Get Position
                vecPos = llGetPos();
                        
                // Build slurl
                strSLURL = "http://slurl.com/secondlife/" + llGetRegionName() + "/" + (string)llRound(vecPos.x) + "/" + (string)llRound(vecPos.y) + "/" + (string)llRound(vecPos.z);

                // Say slurl
                llOwnerSay (strSLURL);                   
            }
            else if (gstrFunction == "listen")
            {
                if (llToLower(llList2String(lstTempCmd, 1)) == "on")
                {
                    llSetScriptState("zAF_ Listener", TRUE);
                    llSetScriptState("zAF_ Listener", TRUE);
                    llOwnerSay("Listening device is now on");
                }
                else if (llToLower(llList2String(lstTempCmd, 1)) == "off")
                {
                    llSetScriptState("zAF_ Listener", FALSE);
                    llOwnerSay("Listening device is now off");
                }
            }
            else if (gstrFunction == "radar")
            {
                if (llToLower(llList2String(lstTempCmd, 1)) == "on")
                {
                    llSetScriptState("zAF_Perfmon", FALSE);
                    llSetScriptState("zAF_Radar", TRUE);
                    llOwnerSay("Radar is now on");
                }
                else if (llToLower(llList2String(lstTempCmd, 1)) == "off")
                {
                    llSetScriptState("zAF_Radar", FALSE);
                    llOwnerSay("Radar is now off");
                    llMessageLinked(-2, 99, "", "");

                }            
            } 
            else if (gstrFunction == "perfmon")
            {
                if (llToLower(llList2String(lstTempCmd, 1)) == "on")
                {
                    llSetScriptState("zAF_Radar", FALSE);
                    llSetScriptState("zAF_Perfmon", TRUE);
                    llOwnerSay("Performance monitoring is now on");
                }
                else if (llToLower(llList2String(lstTempCmd, 1)) == "off")
                {
                    llSetScriptState("zAF_Perfmon", FALSE);
                    llOwnerSay("Performance monitoring is now off");
                    llMessageLinked(-2, 99, "", "");

                }            
            } 
        }
        else if (channel == gintDCC)
        {
            if (message == "1 hour")
            {
                funAction(1.0);
            }
            if (message == "8 hours")
            {
                funAction(8.0);
            }
            if (message == "12 hours")
            {
                funAction(12.0);
            }
            if (message == "1 day")
            {
                funAction(24.0);
            }
            if (message == "7 days")
            {
                funAction(168.0);
            }
            if (message == "15 days")
            {
                funAction(360.0);
            }
            if (message == "30 days")
            {
                funAction(720.0);
            }
            if (message == "Forever")
            {
                funAction(0);
            }
            if (message == "Yes")
            {
                // Turn of Timer and Listners, not needed here
                llListenRemove(gintTempListen);
                llListenRemove(gintTempDCC);
                llSetTimerEvent(0);
                llOwnerSay("Event Canceled");
                funAction(0);
            }
            if (message == "Cancel" || message == "No")
            {
                // Turn of Timer and Listners, not needed here
                llListenRemove(gintTempListen);
                llListenRemove(gintTempDCC);
                llSetTimerEvent(0);
                llOwnerSay("Event Canceled");
            }
        }
    }
    
    link_message(integer sender_num, integer num, string str, key id)
    {
        if ( num == 334)
        {
            gstrURL = str;
        }
    }
    
    http_response(key id, integer status, list meta, string body) 
    {
        if (gintWebRequest == 1)
        {
            //UGLY HACK continuation ... if we already have the key, we ignore the http request result
            if( gkeyAvatar == NULL_KEY && status == 200 )
            {
                // Convert body to list
                list tmpList = llParseString2List(body,[":"],[""]);
                
                gkeyAvatar = llList2String(tmpList,1);
                gstrAvatar = llList2String(tmpList,0);
            }
        
            if( gkeyAvatar == NULL_KEY )
            {
                llDialog(llGetOwner(),"ERROR!\nUnable to retrieve the key for resident\n'" + gstrAvatar + "'\n\nYou may want to input the key\ndirectly in place of the name",["Close"],-42);
                return;
            }
        
            // Set timer to 30 seconds
            llSetTimerEvent(30);  
            
            // Listen for input from dialog box. 
            gintTempDCC = llListen(gintDCC, "", llGetOwner(), "");
                            
            if (gstrFunction == "ban")
            {
                string strBanLenTxt = "Please select the length of time you would like to ban " + gstrAvatar + ".  You can select any length you want, but 30 days is standard.  Please only use forever for the worst cases.\n Cancel will end the ban process.";
                llDialog(llGetOwner(),strBanLenTxt,["30 days","Forever","Cancel","1 day","7 days","15 days","1 hour","8 hours","12 hours"],gintDCC);
            }
            else if (gstrFunction == "eject")
            {
                llDialog(llGetOwner(), "Are you sure you want to eject " + gstrAvatar + "?", ["Yes", "No"], gintDCC);               
            }
            else if (gstrFunction == "home")
            {
                llDialog(llGetOwner(), "Are you sure you want to send " + gstrAvatar + " home ?", ["Yes", "No"], gintDCC);
            }
            else if (gstrFunction == "unban")
            {
                llDialog(llGetOwner(), "Are you sure you want to unban " + gstrAvatar + "?", ["Yes", "No"], gintDCC);               
            }                     
            else if (gstrFunction == "info")
            {
                // Turn of Timer and Listners, not needed here
                llListenRemove(gintTempListen);
                llListenRemove(gintTempDCC);
                llSetTimerEvent(0);
        
                vector size = llGetAgentSize(gkeyAvatar); 
                if (size.z > 0)
                {
                    string strSLURL;
                    vector vecPos;
                                    
                    // Get Position
                    vecPos = (vector)llList2String(llGetObjectDetails(body,[OBJECT_POS]),0);
                            
                    // Build slurl
                    strSLURL = "http://slurl.com/secondlife/" + llGetRegionName() + "/" + (string)llRound(vecPos.x) + "/" + (string)llRound(vecPos.y) + "/" + (string)llRound(vecPos.z); 
                                
                    gstrInfoMsg = gstrAvatar + " is in the sim. \n              Key: " + (string)body + "\n              Location: " + strSLURL + "\n";
                }
                else
                {
                    gstrInfoMsg = gstrAvatar  + " is not in the sim.\n";
                }
                gintWebRequest = 2;
                // Get event information
                reqid = llHTTPRequest(gstrURL + "simnet_eventsearch.php?Search=" + llEscapeURL(gstrAvatar), [], ""); 
            }      
        }
        else if (gintWebRequest == 2)
        {
            llOwnerSay(gstrInfoMsg + "\n" + body);  
        }
    } 
       
    timer()
    {
        // Turn of Timer and Listners, not needed here
        llListenRemove(gintTempListen);
        llListenRemove(gintTempDCC);
        llSetTimerEvent(0);
    }
    
    on_rez(integer start_param)
    {
        llResetScript();    
    }
}

